﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using HM.DataAccessLayer.DTO;
using Npgsql;


namespace HM.DataAccessLayer
{
    /// <summary>
    /// Data Acces layer class that use a reader to retrieve information from database
    /// </summary>
    public class CoreReader  
    {
        private readonly NpgsqlConnection _conn=new NpgsqlConnection();
        


        /// <summary>
        /// Constructor of the class that will connect to the HoldemNanager Database
        /// </summary>
        /// <param name="serverIp"></param>
        /// <param name="serverPort"></param>
        /// <param name="serverLogin"></param>
        /// <param name="serverPassword"></param>
        /// <param name="serverDataBaseName"></param>
        public CoreReader(string serverIp,string serverPort,string serverLogin,string serverPassword,string serverDataBaseName)
        {

            //initialising conncetions tring
            _conn.ConnectionString = string.Format("Server={0};Port={1};Database={2};User Id={3};Password={4};",serverIp,serverPort,serverDataBaseName, serverLogin,serverPassword);

            //opening
            _conn.Open();
            //S_conn.Close();
            

        }


        /// <summary>
        /// Return the current stats for a player for a specific period of time
        /// </summary>
        /// <param name="playerId">The Id of the palyer as identified in the Holdem Manager DataBase</param>
        /// <param name="startDate" />
        /// <param name="endDate"></param>
        /// <param name="pokerSite"></param>
        /// <param name="vppMultiplicator">The VPP multiplicator for computing the FPP earned for this Vip Status
        /// 1 for BronzeStar,1.50 For SilverStar,2 for GoldStar, 2.5 for SuperNova, 4 for SuperNova Elite</param>
        /// <returns>The stats for this player for the current date, null if no stats are found</returns>
        public DTO.PlayerStats GetPlayerStats(PokerSites pokerSite,  Int32 playerId,DateTime startDate, DateTime endDate)
        {
             //setting the value
            PlayerStats s = new PlayerStats();

            //querying the database using a reader
            NpgsqlCommand cmd = new NpgsqlCommand();
            cmd.CommandType = CommandType.Text;

            if (_conn.State == ConnectionState.Closed)
                _conn.Open();

            cmd.Connection = _conn;

            //definiing the FilediltyPointMultiplicator by raked Euro
            double FilediltyPointMultiplicator = 1;
            switch (pokerSite)
            {
                case PokerSites.Ps:
                    FilediltyPointMultiplicator=6;            //6 for each euros raked
                    break;
                case PokerSites.Ft:
                    FilediltyPointMultiplicator=10*1.3;            //10 Fpp * Euro mulitplicator for each euros raked
                    
                    break;
                case PokerSites.Wnm:
                    FilediltyPointMultiplicator=4;            //4 Miles for each euros raked
                    break;
                case PokerSites.Evt:
                    FilediltyPointMultiplicator = 7;            //7 Points summit for each euros raked
               
                    break;
                default:
                    throw new ArgumentOutOfRangeException("pokerSite");
            }

            cmd.CommandText = SqlStatements.GetSqlHandsRakeAmountWon(playerId, startDate, endDate);
            NpgsqlDataReader dataReader = cmd.ExecuteReader();
            
            //if the data is found returning data
            if(dataReader.Read())
            {

                s.PlayerId = playerId;
                s.DateStart = startDate;
                s.DateEnd = endDate;
                if(dataReader["nbhands"]!=DBNull.Value  )
                    s.NbCashHands = Convert.ToInt32(dataReader["nbhands"]);


                if (dataReader["netamountwon"] != DBNull.Value)
                    s.AmountWon = Convert.ToDouble(dataReader["netamountwon"])*0.01;
                
                
                if (dataReader["rakeamount"] != DBNull.Value)
                    s.AmountRaked = Convert.ToDouble(dataReader["rakeamount"])*0.01;

                //managing the VPP and FPP earned
                s.FidelityPointEarned = s.AmountRaked * FilediltyPointMultiplicator;                //each Euro raked equals 7.5 VPP
                s.FppEarned = 0;    //getting the Corresponding FPP

            }
            dataReader.Close();

            //for each player found, setting detailled stats
            if (s.PlayerId > 0)
            {
                
                cmd.CommandText = SqlStatements.GetSqlSimplifiedStats(playerId, startDate, endDate);
                NpgsqlDataReader statsReader = cmd.ExecuteReader();
                while(statsReader.Read())
                {
                    PlayerStatsDetail stat = new PlayerStatsDetail();

                    if (statsReader["gametype"] != DBNull.Value)
                        stat.GameType = (statsReader["gametype"]).ToString();

                    if (statsReader["bigblindvalue"] != DBNull.Value)
                        stat.BigBlindValue = Convert.ToDouble(statsReader["bigblindvalue"]) * 0.01;

                    if (statsReader["totalhands"] != DBNull.Value)
                        stat.NbHands = Convert.ToInt32(statsReader["totalhands"]);

                    if (statsReader["vpiphands"] != DBNull.Value)
                        stat.NbHandVpip = Convert.ToInt32(statsReader["vpiphands"]);


                    if (statsReader["netamountwon"] != DBNull.Value)
                        stat.AmountWon = Convert.ToDouble(statsReader["netamountwon"])/100;
                   
                    s.SessionsDetailledStats.Add(stat);
                }
                statsReader.Close();

            }
            
           
            return s;
          }
    
        /// <summary>
        /// Return a Player by its name and its site
        /// </summary>
        /// <param name="playerName">The Palyer name to found</param>
        /// <param name="pokerSite">PokerSite to find the player</param>
        /// <returns></returns>
        public DTO.Players GetPlayerByName(string playerName, PokerSites pokerSite)
        {
            //querying the database using a reader
            NpgsqlCommand cmd = new NpgsqlCommand();
            cmd.CommandType = CommandType.Text;

            if (_conn.State == ConnectionState.Closed)
                _conn.Open();

            cmd.Connection = _conn;

            cmd.CommandText = SqlStatements.GetPokerSitePlayerId(playerName,pokerSite);
            NpgsqlDataReader dataReader = cmd.ExecuteReader();

            //no data found
            if(!dataReader.Read())
            {
                dataReader.Close();
                return null;
            }
            //if the data is found returning data
            Players p = new Players();

            p.player_id = Convert.ToInt32(dataReader["player_id"]);
            p.playername = dataReader["playername"].ToString();
            p.playertype_id= Convert.ToInt32(dataReader["playertype_id"]);
            p.lastplayeddate = Convert.ToDateTime(dataReader["lastplayeddate"]);
            p.playertype_id=Convert.ToInt32(dataReader["playertype_id"]);
            p.site_id=Convert.ToInt32(dataReader["site_id"]);
            p.tourneyhands=Convert.ToInt32(dataReader["tourneyhands"]);
            p.cashhands = Convert.ToInt32(dataReader["cashhands"]);


            dataReader.Close();
            //_conn.Close();
            return p;
        }


    }

    /// <summary>
    /// Known list of PokerSites Managed by the application
    /// </summary>
    public enum PokerSites
    {
        /// <summary>
        /// PokerStars.fr
        /// </summary>
        Ps = 0,
        /// <summary>
        /// FullTilt Poker.fr
        /// </summary>
        Ft = 1,
        /// <summary>
        /// Winamax.Fr
        /// </summary>
        Wnm = 2,
        /// <summary>
        /// EverestPoker.Fr
        /// </summary>
        Evt = 3


    }


}
    


   

    




